#**********************************************************************************
# ccamLoadScenarios.r
# This file contains the code to load multiple ADMB scenarios into an 'opList'
# All filenames and foldernames for ccam are set here.
#
# Author            : Chris Grandin
# Development Date  : December 2011 - September 2012
#
#**********************************************************************************

# ADMB sscam input filenames
fnCCAM <- "starter.ss"

loadScenarios <- function(model="SS",silent=F){
  # Create empty opList object of correct dimensions
  # prefix op is short for output.
  # opList - is a list of length equal to the number of scenario runs
  #        - each scenario list contains the following (indexed by number)
  #          1. Folder name - taken directly from their folder name on the OS.
  #          2. Figure folder name
  #          3. Tables folder name
  #          4. Data Frame representing the ouput of the model (REP file from ADMB)
  #          5. list of Retrospective data (with filenames as $name) - REP file contents
  #          6. MPD data files exist and were loaded correctly
  #          7. MCMC data files exist and were loaded correctly
  #          8. fnSensitivityGroup file exists and was loaded correctly
  #          9. MPD forecasting file exists and was loaded correctly
  #         10. Name of the control file for this scenario
  #         11. Name of the data file for this scenario
  # model is either "SS" or "CCAM"

  setupFilenames(model)

  opList <<- rep(list(list("","","",NULL,NULL,NULL,NULL,NULL,NULL,"","")),length(dirList))
  for(scenario in 1:(length(dirList))){
    loadScenario(scenario=scenario,model=model,silent=silent)
  }
  if(!silent){
    cat("sscam->loadScenarios: opList now contains all model data.\n")
  }
}

loadScenario <- function(scenario,model,silent=F){
  # Load an individual scenario
  # model is either "SS" or "CCAM"
  # the model outputs are not standardized so the loading code has to be
  #  rewritten for each one.

  # Try creating the opList for each Scenario.
  opList[[scenario]][[1]] <<- dirList[[scenario]]
  fdScenario <- paste(fdScenarios,dirList[[scenario]],"/",sep="")
  opList[[scenario]][[1]] <<- fdScenario
  opList[[scenario]][[2]] <<- paste(fdScenario,fdFigures,sep="")
  opList[[scenario]][[3]] <<- paste(fdScenario,fdTables,sep="")

  cat("-----------------------------------------------------------------------------------\n")
  cat("sscam->loadScenario: Attempting to load scenario",scenario,"\n")
  if(model=="SS"){
    # Try to load MPD results.  If they don't exist then set a global variable to reflect this
    opList[[scenario]][[6]] <<- TRUE
    tryCatch({
      suppressWarnings(
        opList[[scenario]][[4]] <<- SS_output(dir=fdScenario,
                                              verbose=F,
                                              printstats=F,
                                              NoCompOK=T,
                                              covar=F)
      )
    },error=function(err){
      opList[[scenario]][[6]] <<- FALSE
      cat(paste("sscam->loadScenario: No MPD output found for scenario '",fdScenario,"'.\n",sep=""))
    })
    # Try to load MCMC results.  If they don't exist then set a global variable to reflect this
    opList[[scenario]][[7]] <<- TRUE
    tryCatch({
      suppressWarnings(
        opList[[scenario]][[4]]$mcmc <<- SSgetMCMC(dir=fdScenario,
                                                   verbose=F)
      )
    },error=function(err){
      opList[[scenario]][[7]] <<- FALSE
      browser()
      cat(paste("sscam->loadScenario: No MCMC output found for scenario '",fdScenario,"'.\n",sep=""))
    })

    # load in the Control file name and Data file name from fnCCAM (ccam.dat) for this scenario
    ccamDataFile <- paste(opList[[scenario]][[1]],fnCCAM,sep="")
    tryCatch({
      suppressWarnings(
        ccamInputFiles <- read.table(ccamDataFile)
        )
      opList[[scenario]][[11]] <<- paste(opList[[scenario]][[1]],ccamInputFiles[1,],sep="")
      opList[[scenario]][[10]] <<- paste(opList[[scenario]][[1]],ccamInputFiles[2,],sep="")
    }, error = function(err){
      cat(paste("sscam->loadScenario: Error reading the Control file or Data file names from",ccamDataFile,"\n\n"))
    })

  }else if(model=="CCAM"){
    fnRep <- paste(fdScenario,fnReport,sep="")
    fnPar <- paste(fdScenario,fnFit,sep="")
    # Try to load MPD results.  If they don't exist then set a global variable to reflect this
    opList[[scenario]][[6]]                     <<- TRUE
    tryCatch({
      # Suppression of warnings for reptoRlist and read.fit is required because there is an NA coercion warning that doesn't matter.
      suppressWarnings(
        if(file.exists(fnRep)){
          opList[[scenario]][[4]]               <<- reptoRlist(fnRep)
        }
        )
      suppressWarnings(
        if(file.exists(fnPar)){
          opList[[scenario]][[4]]$fit           <<- read.fit(fnPar)
        }
        )
      opList[[scenario]][[4]]$yrs               <<- c(opList[[scenario]][[4]]$yr,max(opList[[scenario]][[4]]$yr)+1)
    }, warning = function(war){
      cat(paste("sscam->loadScenario: No MPD output found for scenario '",fdScenario,"'.\n",sep=""))
      #cat(paste("   -",war))
      opList[[scenario]][[6]]                   <<- FALSE
    }, error = function(err){
      cat(paste("sscam->loadScenario: No MPD output found for scenario '",fdScenario,"'.\n",sep=""))
     #cat(paste("   -",err))
      opList[[scenario]][[6]]                   <<- FALSE
    })

    # Load MPD forecast results
    tryCatch({
      opList[[scenario]][[4]]$mlefor            <<- read.table(paste(fdScenario,fnForecastMLE,sep=""),h=T)
    }, error = function(err){
      cat(paste("sscam->loadScenario: No MPD forecasting output found for scenario '",fdScenario,"'.\n",sep=""))
      opList[[scenario]][[6]]                   <<- FALSE
    })

    # Try to load MCMC results.  If they don't exist then set a global variable to reflect this
    tryCatch({
      opList[[scenario]][[4]]$mc                <<- read.table(paste(fdScenario,fnMCMC,sep=""),h=T)
      opList[[scenario]][[4]]$mcfor             <<- read.table(paste(fdScenario,fnForecastMCMC,sep=""),h=T)
      opList[[scenario]][[4]]$mc.rt             <<- read.table(paste(fdScenario,fnRecruitment,sep=""))
      opList[[scenario]][[4]]$mc.sbt            <<- read.table(paste(fdScenario,fnSBiomass,sep=""))
      opList[[scenario]][[4]]$mc.ft             <<- read.table(paste(fdScenario,fnFishingMort,sep=""))
      opList[[scenario]][[4]]$mc.spr            <<- read.table(paste(fdScenario,fnSpawnersPR,sep=""))
      opList[[scenario]][[4]]$mc.sprstatus_fmsy <<- read.table(paste(fdScenario,fnSPRStatus,sep=""))
      opList[[scenario]][[4]]$mc.sprstatus_f40  <<- read.table(paste(fdScenario,fnSPR40,sep=""))
      opList[[scenario]][[4]]$mc.bt3            <<- read.table(paste(fdScenario,fnBiomass3Plus,sep=""))
      opList[[scenario]][[4]]$mc.bt             <<- read.table(paste(fdScenario,fnBiomass,sep=""))
      opList[[scenario]][[4]]$mc.resid          <<- read.table(paste(fdScenario,fnSurveyResid,sep=""))
      opList[[scenario]][[4]]$mc.sbdepletion    <<- read.table(paste(fdScenario,fnDepletion,sep=""))
      opList[[scenario]][[4]]$equil             <<- read.table(paste(fdScenario,fnEquilibrium,sep=""),h=T)
      opList[[scenario]][[4]]$mcRefPoints       <<- read.table(paste(fdScenario,fnRefPoints,sep=""),h=T)
      opList[[scenario]][[4]]$mc.RecDevs        <<- read.table(paste(fdScenario,fnRecDevs,sep=""),h=F)
      opList[[scenario]][[7]]                   <<- TRUE
    }, warning = function(war){
      cat(paste("sscam->loadScenario: No MCMC output found for scenario '",fdScenario,"'",sep=""))
      if(opList[[scenario]][[6]]){
        cat(", using MPD output only.")
      }
      cat("\n")
      #cat(paste("  -",war,"\n"))
      opList[[scenario]][[7]]                   <<- FALSE
    }, error = function(err){
      cat(paste("sscam->loadScenario: No MCMC output loaded for scenario '",fdSceanrio,"'\n"))
    })

    # Try loading all the retrospective files for this scenario
    # get ret* filenames..
    dirScenario <- dir(fdScenario)
    retLoc <- grep(paste(fnRetro,"[0-9]+",sep=""),dirScenario,T)
    # retLoc gives the indexes for all ret* files
    # create a list structure for the ret* outputs
    opList[[scenario]][[5]] <<- rep(list(NULL),length(retLoc))
    if(length(retLoc>0)){
      for(retro in 1:length(retLoc)){
        opList[[scenario]][[5]][[retro]]      <<- try(reptoRlist(paste(fdScenario,dirScenario[retLoc[retro]],sep="")),silent=silent)
        opList[[scenario]][[5]][[retro]]$name <<- dirScenario[retLoc[retro]]
      }
    }
    # End of loading of retrospectives

    if(!silent){
      cat("sscam->loadScenario:",opList[[scenario]][[1]]," - load complete.\n")
    }

    # load in the Control file name and Data file name from fnCCAM (ccam.dat) for this scenario
    ccamDataFile <- paste(opList[[scenario]][[1]],fnCCAM,sep="")
    tryCatch({
      suppressWarnings(
        ccamInputFiles <- read.table(ccamDataFile)
        )
      opList[[scenario]][[10]] <<- paste(opList[[scenario]][[1]],ccamInputFiles[2,],sep="")
      opList[[scenario]][[11]] <<- paste(opList[[scenario]][[1]],ccamInputFiles[1,],sep="")
    }, error = function(err){
      cat(paste("sscam->loadScenario: Error reading the Control file or Data file names from",ccamDataFile,"\n"))
    })

  }

  # Try to load Scenario's sensitivity group file.  If it doesn't exist then set a scenario variable to reflect this
  tryCatch({
    opList[[scenario]][[4]]$SensitivityGroup  <<- read.table(paste(fdScenario,fnSensitivityGroup,sep=""))[,1]
    opList[[scenario]][[8]]                   <<- TRUE
  }, warning = function(war){
    cat(paste("sscam->loadScenario: No ",fnSensitivityGroup," file found for scenario '",fdScenario,"'.\nStopping......"))
    opList[[scenario]][[8]]                   <<- FALSE
    stop()
  })

  # Make sure the figures and tables directories exist, if not, create them
  tmpFdFigures <- paste(fdScenario,fdFigures,sep="")
  tmpFdTables <- paste(fdScenario,fdTables,sep="")
  dir.create(tmpFdFigures,showWarnings=!silent)
  dir.create(tmpFdTables,showWarnings=!silent)
  cat("sscam->loadScenario: Finished loading scenario",scenario,"\n")
  cat("-----------------------------------------------------------------------------------\n\n")
}

setupFilenames <- function(model){
  # setup the folder and filenames based on the model.
  # model must be "SS" or "CCAM"

  # Set up folder structure - prefix fd means foldername - all folders here must have trailing '/'
  fdADMB                  <<- "../admb/"  # location of the TPL and EXE for ccam.
  fdControlFiles          <<- "../admb/"  # location to which the admb .CTL and .DAT files are copied
  fdScenarios             <<- "../Scenarios/"
  fdFigures               <<- "figs/"
  fdTables                <<- "tables/"
  dirList                 <<- dir(fdScenarios)
  # Model executable name
  exModel                 <<- "SS-V3.24f_safe-Win64"

  # No files defined for SS because r4ss package takes care of this.

  fnSensitivityGroup      <<- "SensitivityGroup.txt"
}
